#!/bin/bash

# 配置管理系统 / Configuration Management System
# 提供配置文件生成、验证、备份和修复功能

# 导入环境检测模块
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/environment-detector.sh"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置模板目录
TEMPLATE_DIR="$SCRIPT_DIR/../templates"
BACKUP_DIR="/tmp/personal-cloud-notes-config-backup-$(date +%Y%m%d-%H%M%S)"

# 函数：创建配置备份
backup_config() {
    local config_file="$1"
    local backup_name="$2"
    
    if [[ ! -f "$config_file" ]]; then
        echo "配置文件不存在: $config_file"
        return 1
    fi
    
    mkdir -p "$BACKUP_DIR"
    local backup_file="$BACKUP_DIR/${backup_name:-$(basename "$config_file")}.backup"
    
    cp "$config_file" "$backup_file"
    echo "配置已备份到: $backup_file"
    return 0
}

# 函数：恢复配置备份
restore_config() {
    local backup_file="$1"
    local target_file="$2"
    
    if [[ ! -f "$backup_file" ]]; then
        echo "备份文件不存在: $backup_file"
        return 1
    fi
    
    cp "$backup_file" "$target_file"
    echo "配置已恢复: $target_file"
    return 0
}

# 函数：生成Nginx配置
generate_nginx_config() {
    local output_file="${1:-/etc/nginx/nginx.conf}"
    local web_user="${2:-$(detect_web_user)}"
    local worker_processes="${3:-auto}"
    
    echo "生成Nginx配置文件: $output_file"
    echo "使用Web用户: $web_user"
    
    # 备份现有配置
    if [[ -f "$output_file" ]]; then
        backup_config "$output_file" "nginx.conf"
    fi
    
    # 生成新配置
    cat > "$output_file" << EOF
# 个人云笔记 Nginx 主配置文件
# Personal Cloud Notes Nginx Main Configuration
# 自动生成于: $(date)

# 运行用户和组
user $web_user;

# 工作进程数，建议设置为CPU核心数
worker_processes $worker_processes;

# 错误日志路径和级别
error_log /var/log/nginx/error.log warn;

# PID文件路径
pid /var/run/nginx.pid;

# 事件模块配置
events {
    # 每个工作进程的最大连接数
    worker_connections 1024;
    
    # 使用epoll事件模型（Linux推荐）
    use epoll;
    
    # 允许一个工作进程同时接受多个新连接
    multi_accept on;
}

# HTTP模块配置
http {
    # MIME类型配置
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # 日志格式定义
    log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                    '\$status \$body_bytes_sent "\$http_referer" '
                    '"\$http_user_agent" "\$http_x_forwarded_for" '
                    'rt=\$request_time uct="\$upstream_connect_time" '
                    'uht="\$upstream_header_time" urt="\$upstream_response_time"';
    
    # 访问日志配置
    access_log /var/log/nginx/access.log main;
    
    # 性能优化配置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    
    # 隐藏Nginx版本信息
    server_tokens off;
    
    # 客户端请求体大小限制（支持大文件上传）
    client_max_body_size 100M;
    client_body_buffer_size 128k;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    
    # 超时设置
    client_body_timeout 60s;
    client_header_timeout 60s;
    send_timeout 60s;
    
    # Gzip压缩配置
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;
    
    # 安全头配置
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 速率限制配置
    limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone \$binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone \$binary_remote_addr zone=upload:10m rate=2r/s;
    
    # 连接限制配置
    limit_conn_zone \$binary_remote_addr zone=perip:10m;
    limit_conn_zone \$server_name zone=perserver:10m;
    
    # 上游服务器配置
    upstream personal_cloud_notes_backend {
        # Node.js应用服务器
        server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
        
        # 负载均衡方法
        least_conn;
        
        # 保持连接
        keepalive 32;
    }
    
    # 包含站点配置文件
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF
    
    echo "Nginx配置文件已生成"
    return 0
}

# 函数：验证Nginx配置
validate_nginx_config() {
    local config_file="${1:-/etc/nginx/nginx.conf}"
    
    echo "验证Nginx配置: $config_file"
    
    if nginx -t -c "$config_file" 2>/dev/null; then
        echo -e "${GREEN}✓ Nginx配置验证通过${NC}"
        return 0
    else
        echo -e "${RED}✗ Nginx配置验证失败${NC}"
        nginx -t -c "$config_file"
        return 1
    fi
}

# 函数：自动修复Nginx配置
auto_fix_nginx_config() {
    local config_file="${1:-/etc/nginx/nginx.conf}"
    
    echo "自动修复Nginx配置: $config_file"
    
    if [[ ! -f "$config_file" ]]; then
        echo "配置文件不存在，生成新配置"
        generate_nginx_config "$config_file"
        return $?
    fi
    
    # 备份原配置
    backup_config "$config_file" "nginx-before-fix.conf"
    
    # 检测并修复常见问题
    local web_user=$(detect_web_user)
    local fixes_applied=0
    
    # 修复用户配置
    if grep -q "user nginx;" "$config_file" && [[ "$web_user" != "nginx" ]]; then
        echo "修复Web用户配置: nginx -> $web_user"
        sed -i "s/user nginx;/user $web_user;/g" "$config_file"
        fixes_applied=$((fixes_applied + 1))
    fi
    
    # 修复PID文件路径
    if ! grep -q "pid /var/run/nginx.pid;" "$config_file"; then
        echo "添加PID文件配置"
        sed -i '/user /a pid /var/run/nginx.pid;' "$config_file"
        fixes_applied=$((fixes_applied + 1))
    fi
    
    # 验证修复结果
    if validate_nginx_config "$config_file"; then
        echo -e "${GREEN}配置修复成功，应用了 $fixes_applied 个修复${NC}"
        return 0
    else
        echo -e "${RED}配置修复失败，恢复备份${NC}"
        restore_config "$BACKUP_DIR/nginx-before-fix.conf.backup" "$config_file"
        return 1
    fi
}

# 函数：生成站点配置
generate_site_config() {
    local site_name="${1:-personal-cloud-notes}"
    local domain="${2:-localhost}"
    local app_port="${3:-3000}"
    local ssl_enabled="${4:-false}"
    local output_file="/etc/nginx/sites-available/$site_name"
    
    echo "生成站点配置: $site_name"
    
    # 创建目录
    mkdir -p /etc/nginx/sites-available
    mkdir -p /etc/nginx/sites-enabled
    
    # 备份现有配置
    if [[ -f "$output_file" ]]; then
        backup_config "$output_file" "$site_name.conf"
    fi
    
    # 生成配置
    if [[ "$ssl_enabled" == "true" ]]; then
        generate_ssl_site_config "$site_name" "$domain" "$app_port" "$output_file"
    else
        generate_http_site_config "$site_name" "$domain" "$app_port" "$output_file"
    fi
    
    # 启用站点
    if [[ ! -L "/etc/nginx/sites-enabled/$site_name" ]]; then
        ln -s "$output_file" "/etc/nginx/sites-enabled/$site_name"
        echo "站点已启用: $site_name"
    fi
    
    return 0
}

# 函数：生成HTTP站点配置
generate_http_site_config() {
    local site_name="$1"
    local domain="$2"
    local app_port="$3"
    local output_file="$4"
    
    cat > "$output_file" << EOF
# $site_name HTTP配置
# 自动生成于: $(date)

server {
    listen 80;
    listen [::]:80;
    server_name $domain;
    
    # 网站根目录
    root /var/www/personal-cloud-notes/public;
    index index.html;
    
    # 连接和请求限制
    limit_conn perip 10;
    limit_conn perserver 100;
    
    # 静态文件缓存配置
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header X-Content-Type-Options "nosniff";
        gzip_static on;
    }
    
    # API请求代理配置
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        
        proxy_pass http://127.0.0.1:$app_port;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
        
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
    
    # 登录API特殊限制
    location /api/auth/login {
        limit_req zone=login burst=5 nodelay;
        
        proxy_pass http://127.0.0.1:$app_port;
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
    
    # 文件上传API特殊配置
    location /api/files/upload {
        limit_req zone=upload burst=5 nodelay;
        client_max_body_size 100M;
        client_body_timeout 300s;
        
        proxy_pass http://127.0.0.1:$app_port;
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        
        proxy_connect_timeout 60s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
        proxy_request_buffering off;
    }
    
    # 健康检查端点
    location /health {
        proxy_pass http://127.0.0.1:$app_port;
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
        proxy_connect_timeout 5s;
        proxy_send_timeout 5s;
        proxy_read_timeout 5s;
        access_log off;
    }
    
    # 默认路由 - SPA支持
    location / {
        try_files \$uri \$uri/ /index.html;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
    }
    
    # 禁止访问敏感文件
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    location ~* \.(env|log|sql)$ {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 错误页面配置
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
}
EOF
}

# 函数：生成数据库配置
generate_database_config() {
    local db_user="${1:-notes_user}"
    local db_password="${2:-$(generate_secure_password)}"
    local db_name="${3:-personal_cloud_notes}"
    local output_file="${4:-/tmp/database-config.env}"
    
    echo "生成数据库配置文件: $output_file"
    
    cat > "$output_file" << EOF
# 数据库配置
# 自动生成于: $(date)

DB_HOST=localhost
DB_PORT=3306
DB_NAME=$db_name
DB_USER=$db_user
DB_PASSWORD=$db_password
EOF
    
    chmod 600 "$output_file"
    echo "数据库配置已生成并设置安全权限"
    echo "数据库用户: $db_user"
    echo "数据库名称: $db_name"
    return 0
}

# 函数：生成应用配置
generate_app_config() {
    local app_port="${1:-3000}"
    local node_env="${2:-production}"
    local jwt_secret="${3:-$(generate_secure_password 64)}"
    local output_file="${4:-/var/www/personal-cloud-notes/.env}"
    
    echo "生成应用配置文件: $output_file"
    
    # 创建目录
    mkdir -p "$(dirname "$output_file")"
    
    # 备份现有配置
    if [[ -f "$output_file" ]]; then
        backup_config "$output_file" "app.env"
    fi
    
    cat > "$output_file" << EOF
# 个人云笔记应用配置
# 自动生成于: $(date)

# 环境配置
NODE_ENV=$node_env
PORT=$app_port

# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=personal_cloud_notes
DB_USER=notes_user
DB_PASSWORD=\${DB_PASSWORD}

# JWT配置
JWT_SECRET=$jwt_secret
JWT_EXPIRES_IN=7d

# 文件上传配置
UPLOAD_PATH=/var/www/personal-cloud-notes/data/users
MAX_FILE_SIZE=104857600
MAX_IMAGE_SIZE=5242880
MAX_VIDEO_SIZE=52428800
MAX_AUDIO_SIZE=10485760

# 存储配置
DEFAULT_STORAGE_LIMIT=32212254720

# 安全配置
BCRYPT_ROUNDS=10
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100

# 备份配置
BACKUP_PATH=/var/www/personal-cloud-notes/data/backups
BACKUP_RETENTION_DAYS=7

# 日志配置
LOG_LEVEL=info
LOG_PATH=/var/www/personal-cloud-notes/data/logs
LOG_ENABLE_CONSOLE=false
LOG_ENABLE_FILE=true

# 性能监控配置
ENABLE_PERFORMANCE_MONITORING=true
METRICS_INTERVAL=30000

# 缓存配置
ENABLE_STATIC_CACHE=true
STATIC_CACHE_MAX_AGE=86400
ENABLE_GZIP=true
EOF
    
    chmod 600 "$output_file"
    echo "应用配置已生成并设置安全权限"
    return 0
}

# 函数：生成安全密码
generate_secure_password() {
    local length="${1:-32}"
    openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length"
}

# 函数：验证配置文件语法
validate_config_syntax() {
    local config_file="$1"
    local config_type="$2"
    
    case "$config_type" in
        "nginx")
            validate_nginx_config "$config_file"
            ;;
        "env")
            # 验证环境变量文件语法
            if bash -n "$config_file" 2>/dev/null; then
                echo -e "${GREEN}✓ 环境配置语法正确${NC}"
                return 0
            else
                echo -e "${RED}✗ 环境配置语法错误${NC}"
                return 1
            fi
            ;;
        *)
            echo "不支持的配置类型: $config_type"
            return 1
            ;;
    esac
}

# 函数：应用配置更改
apply_config_changes() {
    local config_file="$1"
    local service_name="$2"
    
    echo "应用配置更改: $config_file -> $service_name"
    
    case "$service_name" in
        "nginx")
            if validate_nginx_config "$config_file"; then
                systemctl reload nginx
                echo "Nginx配置已重新加载"
            else
                echo "配置验证失败，未应用更改"
                return 1
            fi
            ;;
        "personal-cloud-notes")
            # 重启应用服务
            if command -v pm2 >/dev/null 2>&1; then
                pm2 restart personal-cloud-notes 2>/dev/null || true
            fi
            echo "应用配置已应用"
            ;;
        *)
            echo "不支持的服务: $service_name"
            return 1
            ;;
    esac
    
    return 0
}

# 主函数：配置管理入口
main() {
    local action="$1"
    shift
    
    case "$action" in
        "generate-nginx")
            generate_nginx_config "$@"
            ;;
        "fix-nginx")
            auto_fix_nginx_config "$@"
            ;;
        "generate-site")
            generate_site_config "$@"
            ;;
        "generate-app")
            generate_app_config "$@"
            ;;
        "generate-db")
            generate_database_config "$@"
            ;;
        "validate")
            validate_config_syntax "$@"
            ;;
        "backup")
            backup_config "$@"
            ;;
        "restore")
            restore_config "$@"
            ;;
        *)
            echo "用法: $0 {generate-nginx|fix-nginx|generate-site|generate-app|generate-db|validate|backup|restore} [参数...]"
            exit 1
            ;;
    esac
}

# 如果直接运行此脚本
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi